<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="WdFDl" id="WdFDl"><span data-lake-id="ua5c5d734" id="ua5c5d734">典型回答</span></h1>
  <p data-lake-id="ucee42e5f" id="ucee42e5f"><br></p>
  <p data-lake-id="u86f44e23" id="u86f44e23"><span data-lake-id="u18fd00e6" id="u18fd00e6">在MySQL中，主键非常重要，因为Innodb中的主键索引是用来构建聚簇索引的。</span></p>
  <p data-lake-id="ue34dcbe0" id="ue34dcbe0"><span data-lake-id="uc59fc601" id="uc59fc601">​</span><br></p>
  <p data-lake-id="u4dca7944" id="u4dca7944"><strong><span data-lake-id="u24ec7cbe" id="u24ec7cbe">如果我们在一张表中没有定义主键，那么，MySQL会默认选择一个唯一的非空索引作为聚簇索引。如果没有适合的非空唯一索引，则会创建一个隐藏的主键（row_id）作为聚簇索引。</span></strong></p>
  <p data-lake-id="u3a282c55" id="u3a282c55"><strong><span data-lake-id="uad0c7475" id="uad0c7475">​</span></strong><br></p>
  <p data-lake-id="ub0b8bd75" id="ub0b8bd75"><span data-lake-id="u960a3741" id="u960a3741">那么也就是说，一个Innodb的表中，是一定会有主键索引的。</span></p>
  <p data-lake-id="uf0ca22c0" id="uf0ca22c0"><span data-lake-id="ub537353b" id="ub537353b">​</span><br></p>
  <p data-lake-id="u7daa5dc8" id="u7daa5dc8"><span data-lake-id="ud0f79a10" id="ud0f79a10">那同时，我们也知道，</span><strong><span data-lake-id="u44a30fcc" id="u44a30fcc">InnoDB行锁是通过给索引上的索引项加锁来实现的，如果一条记录没有创建索引，那么他会选择锁表。行级锁会升级为表级锁。</span></strong></p>
  <p data-lake-id="u17ecd303" id="u17ecd303"><span data-lake-id="u1aca4108" id="u1aca4108">​</span><br></p>
  <p data-lake-id="ueb6dc082" id="ueb6dc082"><span data-lake-id="u75f36013" id="u75f36013">那么问题来了：MySQL不是会默认添加主键索引，为啥还会有锁表的情况呢？</span></p>
  <p data-lake-id="u4eb617dc" id="u4eb617dc"><span data-lake-id="u45610598" id="u45610598">​</span><br></p>
  <p data-lake-id="u8a744385" id="u8a744385"><span data-lake-id="u446d3e49" id="u446d3e49">其实，索引，并不只是主键索引，还有很多普通索引呢，我们大多数查询都是基于普通索引的，而数据库在加锁的时候，也会先对普通索引加锁，然后再回表对主键索引加锁。</span></p>
  <p data-lake-id="u430f908c" id="u430f908c"><span data-lake-id="ub775765d" id="ub775765d">​</span><br></p>
  <p data-lake-id="uf7601c24" id="uf7601c24"><span data-lake-id="u3cb6f6e8" id="u3cb6f6e8">那么，如果一个update语句的where条件中的字段，用不到普通索引，这时候他就没办法对普通索引加行级锁，那么就需要锁表了。</span></p>
  <p data-lake-id="uada68c9c" id="uada68c9c"><span data-lake-id="uf7e72928" id="uf7e72928">​</span><br></p>
  <p data-lake-id="uc4b8b082" id="uc4b8b082"><span data-lake-id="ud658e55a" id="ud658e55a">虽然这张表可能有主键索引，但是在更新这个过程因为不知道要找哪个索引树（因为没普通索引），那么就干脆锁表了。</span></p>
 </body>
</html>